package com.zzs.covid19_view.service.impl;

import com.zzs.covid19_view.common.config.Crawler;
import com.zzs.covid19_view.common.config.Parse;
import com.zzs.covid19_view.common.entity.*;
import com.zzs.covid19_view.common.utils.JsoupUtil;
import com.zzs.covid19_view.common.utils.SnowFlakeUtil;
import com.zzs.covid19_view.dao.AreaStatMapper;
import com.zzs.covid19_view.dao.StatisticsMapper;
import com.zzs.covid19_view.dao.TimeLineMapper;
import com.zzs.covid19_view.service.DataService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 文件名: DataServiceImpl
 * 创建者: zzs
 * 创建时间: 2021/8/12 10:17
 * 描述:  数据DataServiceImpl,用来从爬虫爬取的数据,存到数据库
 */
@Service
@Transactional
@Slf4j
public class DataServiceImpl implements DataService {

    @Autowired
    private StatisticsMapper statisticsMapper;
    @Autowired
    private TimeLineMapper timeLineMapper;
    @Autowired
    private AreaStatMapper areaStatMapper;

    /**
     * 爬取获取数据存到数据库
     */
    @Override
    public void getInformation() {
        //获取html数据
        JsoupUtil.getPageByJSoup(Crawler.URL);
        //提取静态static内的json数据
        String statisticsInfo = null;
        Statistics statistics = null;
        try {
            statisticsInfo = JsoupUtil.getInformation(Crawler.STATISTICS_REGEX_TEMPLATE_1, "id", Crawler.STATISTICS_ATTRIBUTE);
            //去掉static数据正则1匹配最后的 }catch(e){}串， 剩下的就是一个格式正确的json串了
            statisticsInfo = statisticsInfo.replace("}catch(e){}", "");
            statistics = Parse.parseStatisticsInformation(statisticsInfo);
        } catch (Exception e) {
            log.error("static信息正则1匹配失败，切换正则2", e);
            try {
                statisticsInfo = JsoupUtil.getInformation(Crawler.STATISTICS_REGEX_TEMPLATE_2, "id", Crawler.STATISTICS_ATTRIBUTE);
                statistics = Parse.parseStatisticsInformation(statisticsInfo);
            } catch (Exception e1) {
                log.error("static信息正则2匹配失败，切换正则3", e);
                statisticsInfo = JsoupUtil.getInformation(Crawler.STATISTICS_REGEX_TEMPLATE_3, "id", Crawler.STATISTICS_ATTRIBUTE);
                statistics = Parse.parseStatisticsInformation(statisticsInfo);
            }
        }
        log.info("解析结果Statistics:{}", statistics);
        //存储到数据库
        //先去数据库查询最新一条记录
        Statistics statistics_newest = statisticsMapper.selectNewestStatistics();
        if (statistics_newest != null && statistics_newest.equals(statistics)) {
            log.info("信息相同,不用更新");
        } else {
            statistics.setCountRemark("累计确诊 " + statistics.getConfirmedCount() +
                    "例，现存确诊" + statistics.getCurrentConfirmedCount() +
                    "例，重症" + statistics.getSeriousCount() +
                    "例，疑似 " + statistics.getSuspectedCount() +
                    "例，死亡 " + statistics.getDeadCount() +
                    "例，治愈 " + statistics.getCuredCount() + "例");
            int delete = 0;
            if (statistics_newest != null) {
                String oldId = statistics_newest.getId();
                //先删除原来的数据,然后再新增
                delete = statisticsMapper.deleteById(oldId);
                if (delete == 0) {
                    log.info("删除老数据出错");
                    return;
                }
            }
            int insert = statisticsMapper.insert(statistics);
            String increaseMessage = "较昨日增长: " + "<br/>累计确诊：" + statistics.getConfirmedIncr() +
                    "<br/>现存确诊：" + statistics.getCurrentConfirmedIncr() +
                    "<br/>重症：" + statistics.getSeriousIncr() +
                    "<br/>疑似：" + statistics.getSuspectedIncr() +
                    "<br/>死亡：" + statistics.getDeadIncr() +
                    "<br/>治愈：" + statistics.getCuredIncr();
            if (insert > 0 || delete > 0) {
                //总数据有变化,更新省份信息
                //提取其他信息的json数据
                String timeLineInfo = JsoupUtil.getInformation(Crawler.TIME_LINE_REGEX_TEMPLATE, "id", Crawler.TIME_LINE_ATTRIBUTE);
                String areaInfo = JsoupUtil.getInformation(Crawler.AREA_INFORMATION_REGEX_TEMPLATE, "id", Crawler.AREA_INFORMATION_ATTRIBUTE);
                //解析
                List<TimeLine> timeLines = Parse.parseTimeLineInformation(timeLineInfo);
                List<AreaStat> areaStats = Parse.parseAreaInformation(areaInfo);
                //先根据timeLines中的id去数据库查询是否已存在,不存在,再新增,其实此处不用考虑,因为这个定时任务,只有在每天凌晨才会执行一次,所以不会重复,只是现在本地每隔一分钟执行一次,就会有重复的id
                //批量更新到数据库
                int batchInsert = timeLineMapper.batchInsert(timeLines);
                for (AreaStat areaStat : areaStats) {
                    String provinceName = areaStat.getProvinceName();
                    //根据省份名称查询省份信息
                    AreaStat areaStat_mysql = areaStatMapper.selectProvinceByName(provinceName);
                    if (areaStat_mysql == null) {
                        //新增省份
                        areaStat.setModifyTime(System.currentTimeMillis() / 1000);
                        int addProvince = areaStatMapper.insertProvince(areaStat);
                        log.info("新增省份:{}", areaStat);
                    } else {
                        //库中已经有这个省份
                        if (!areaStat.equals(areaStat_mysql)) {
                            areaStat.setModifyTime(System.currentTimeMillis() / 1000);
                            int updateProvince = areaStatMapper.updateProvince(areaStat);
                            log.info("修改省份:{}", areaStat);
                        }
                    }
                    List<AreaStat.CitiesBean> cities = areaStat.getCities();
                    for (AreaStat.CitiesBean city : cities) {
                        city.setProvinceName(provinceName);
                        //根据市名查询市信息
                        AreaStat.CitiesBean areaStat_city = areaStatMapper.selectCityByName(city.getCityName());
                        if (areaStat_city == null) {
                            //新增市
                            city.setModifyTime(System.currentTimeMillis() / 1000);
                            int addCity = areaStatMapper.insertCity(city);
                            log.info("新增市:{}", city);
                        } else {
                            //库中已经存在这个市
                            if (!city.equals(areaStat_city)) {
                                city.setModifyTime(System.currentTimeMillis() / 1000);
                                int updateCity = areaStatMapper.updateCity(city);
                                log.info("修改市:{}", city);
                            }
                        }
                    }
                }
            }
        }
    }

    @Override
    public List<AreaStat> selectAllProvinceData() {
        return areaStatMapper.selectAllProvince();
    }

    @Override
    public Map<String, Object> getCityData(String provinceShortName) {
        String provinceName = provinceShortName + "省";
        if (provinceName.contains("新疆")) {
            provinceName = provinceName.replace("省", "维吾尔自治区");
        } else if (provinceName.contains("西藏")) {
            provinceName = provinceName.replace("省", "自治区");
        } else if (provinceName.contains("宁夏")) {
            provinceName = provinceName.replace("省", "回族自治区");
        } else if (provinceName.contains("广西")) {
            provinceName = provinceName.replace("省", "壮族自治区");
        } else if (provinceName.contains("内蒙古")) {
            provinceName = provinceName.replace("省", "自治区");
        } else if (provinceName.contains("北京")) {
            provinceName = provinceName.replace("省", "市");
        } else if (provinceName.contains("天津")) {
            provinceName = provinceName.replace("省", "市");
        } else if (provinceName.contains("上海")) {
            provinceName = provinceName.replace("省", "市");
        } else if (provinceName.contains("重庆")) {
            provinceName = provinceName.replace("省", "市");
        } else if (provinceName.contains("香港")) {
            provinceName = provinceName.replace("省", "特别行政区");
        } else if (provinceName.contains("澳门")) {
            provinceName = provinceName.replace("省", "特别行政区");
        }
        List<City> cityList = areaStatMapper.selectCityByProvinceName(provinceName);
        //省市名称list
        List<String> nameList = new ArrayList<>();
        //确诊数量list
        List<Integer> confirmedCountList = new ArrayList<>();
        //治愈数量list
        List<Integer> curedCountList = new ArrayList<>();
        //死亡数量list
        List<Integer> deadCountList = new ArrayList<>();
        //疑似数量list
        List<Integer> suspectedCountList = new ArrayList<>();
        List<Map<String, Object>> cityMapList = new ArrayList<>();
        for (City city : cityList) {
            String cityName = city.getCityName();
            int confirmedCount = city.getConfirmedCount();
            int curedCount = city.getCuredCount();
            int deadCount = city.getDeadCount();
            int suspectedCount = city.getSuspectedCount();
            //对市特殊处理
            cityName = cityName + "市";
            if (cityName.contains("恩施州")) {
                cityName = "恩施土家族苗族自治州";
            } else if (cityName.contains("神农架林区")) {
                cityName = "神农架林区";
            } else if (cityName.contains("昌吉州")) {
                cityName = "昌吉回族自治州";
            } else if (cityName.contains("伊犁州")) {
                cityName = "伊犁哈萨克自治州";
            } else if (cityName.contains("兵团第八师石河子市")) {
                cityName = "石河子市";
            } else if (cityName.contains("兵团第六师五家渠市")) {
                cityName = "五家渠市";
            } else if (cityName.contains("巴州")) {
                cityName = "巴音郭楞蒙古自治州";
            } else if (cityName.contains("兵团第七师")) {
                cityName = "胡杨河市";
            } else if (cityName.contains("甘孜州")) {
                cityName = "甘孜藏族自治州";
            } else if (cityName.contains("阿坝州")) {
                cityName = "阿坝藏族羌族自治州";
            } else if (cityName.contains("凉山州")) {
                cityName = "凉山彝族自治州";
            } else if (cityName.contains("海北州")) {
                cityName = "海北藏族自治州";
            }
            city.setCityName(cityName);
            Map<String, Object> cityMap = new HashMap<>();
            cityMap.put("name", cityName);
            cityMap.put("value", confirmedCount);
            cityMapList.add(cityMap);
            nameList.add(cityName);
            confirmedCountList.add(confirmedCount);
            curedCountList.add(curedCount);
            deadCountList.add(deadCount);
            suspectedCountList.add(suspectedCount);
        }
        Map<String, Object> map = new HashMap<>();
        map.put("cityMapList", cityMapList);
        map.put("nameList", nameList);
        map.put("confirmedCountList", confirmedCountList);
        map.put("curedCountList", curedCountList);
        map.put("deadCountList", deadCountList);
        map.put("suspectedCountList", suspectedCountList);
        return map;
    }
}
